#!/usr/bin/python3
# -*- coding: utf-8 -*-
"""
 Copyright © 2017 NeatLogic
"""
import sys
import os
import json
import argparse
import paramiko

import VContext
import Utils
import TagentClient

if __name__ == "__main__":
    # 参数处理
    parser = argparse.ArgumentParser()
    parser.add_argument("--node", default="{}", help='Json, example:{"nodeName":"myNode","protocol":"ssh","password":"{ENCRYPTED}0bad068c79dd721e","resourceId":497544471568384,"host":"192.168.0.101","nodeType":"Linux","protocolPort":22,"username":"root"}')
    parser.add_argument("--verbose", default=0, help="Verbose or not, default:0")
    parser.add_argument("--timeout", default=15, help="Connection timeout, default:15 seconds")

    args = parser.parse_args()
    node = args.node
    if node == "{}":
        node = os.getenv("AUTOEXEC_NODE")
    nodeInfo = json.loads(node)

    host = nodeInfo["host"]
    username = nodeInfo["username"]
    password = nodeInfo["password"]
    if password.startswith("{ENCRYPTED}"):
        vContext = VContext.VContext(0)
        password = Utils._rc4_decrypt_hex(vContext.passKey, password[11:])
    elif password.startswith("{RC4}"):
        vContext = VContext.VContext(0)
        password = Utils._rc4_decrypt_hex(vContext.passKey, password[5:])
    if password.startswith("RC:"):
        vContext = VContext.VContext(0)
        password = Utils._rc4_decrypt_hex(vContext.passKey, password[3:])

    protocol = nodeInfo.get("protocol")
    protocolPort = nodeInfo.get("protocolPort")
    servicePorts = nodeInfo.get("servicePorts")

    if servicePorts is not None:
        servicePort = servicePorts.get(protocol)
        if servicePort is not None and servicePort != "":
            protocolPort = servicePort

    if protocol.startswith("tagent."):
        protocol = "tagent"
        protocolPortTxt = protocol[7:]
        if protocolPortTxt != "":
            protocolPort = int(protocolPortTxt)

    if protocolPort is None or protocolPort == "":
        protocolPort = nodeInfo.get("port", 0)

    hasError = 0

    if protocol == "ssh":
        # 因为部分server可能会不发出公钥散列算法协商
        # 修改paramiko的pub key的优先顺序，吧ssh-sha2放到最后去，否则rsa验证会不通过
        preferPubkeys = paramiko.transport.Transport._preferred_pubkeys
        fixedPubkeys = []
        notPreferPubkeys = []

        for pubKey in preferPubkeys:
            if pubKey.startswith("rsa-sha2-"):
                notPreferPubkeys.append(pubKey)
            else:
                fixedPubkeys.append(pubKey)

        fixedPubkeys.extend(notPreferPubkeys)
        paramiko.transport.Transport._preferred_pubkeys = fixedPubkeys
        # 修复公钥优先顺序结束

        ssh = paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        sys.tracebacklimit = -1
        try:
            ssh.connect(hostname=host, port=protocolPort, username=username, password=password, banner_timeout=10, timeout=10, look_for_keys=True)
            print("INFO: Connect to {}@{}:{} success.".format(username, host, protocolPort))
        except BaseException as ex:
            hasError = 1
            print("ERROR: Connect to {}@{}:{} failed, {}".format(username, host, protocolPort, ex))
        finally:
            if ssh is not None:
                ssh.close()
    elif protocol == "tagent":
        try:
            tagent = TagentClient.TagentClient(host, protocolPort, password=password, connectTimeout=15, readTimeout=360, writeTimeout=10)
            exitCode = tagent.execCmd("root", "echo test")
        except Exception as ex:
            hasError = 1

    exit(hasError)
